﻿/**	canvas.h
 *	----	Create Time Stamp	--2007-02-10 22:50:33--
 *------------------------------------------------------------------------------
 *	Mean	:画布
 *	Author	:Nick Shallery	(nicknide@gmail.com)
 *	Version	:1.0.29.71	(2009-11-02 23:01:20)
 *------------------------------------------------------------------------------
**/	/*YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.*/

#if			!defined(__LOLIX__PRETTY__CANVAS__K_IN_G__)
#define		__LOLIX__PRETTY__CANVAS__K_IN_G__
//==============================================================================
//--------------------------------------------------------------------------

#if			!defined(__LOLIX__SOLA__MATRIX__K_IN_G__)
	#include	"../sola/matrix.h"
#endif	//	!defined(__LOLIX__SOLA__MATRIX__K_IN_G__)
#if			!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
	#include	"../lolix_macro.h"
#endif	//	!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
	#include	"../lolix_type.h"
#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
#if			!defined(__LOLIX__TOY__REBIND_TYPE__K_IN_G__)
	#include	"../toy/rebind_type.hpp"
#endif	//	!defined(__LOLIX__TOY__REBIND_TYPE__K_IN_G__)

namespace lolix{
	namespace sola{
		class dancer;
	}

	namespace loli{
		class file_block;
	}
}

namespace lolix{namespace pretty{
	class	canvas;
	class	canvas_package;
	class	vertex_buffer;
	enum	ENUM_IDX_TYPE{IDX_TYPE_ATTR, IDX_TYPE_UNIF, IDX_TYPE_TEX, _IDX_TYPE_CNT, _IDX_TYPE_VER = 0};
	enum	ENUM_SHADER_TYPE{ sd_v = 0, sd_f = 1, _sd_cnt, _sd_ver = 1};	//	vertex shader, framge shader
	enum	ENUM_PIXEL_TYPE
	{
		PIXEL_TYPE_UNKNOW			,	//	未知
		PIXEL_TYPE_ALPHA			,
		PIXEL_TYPE_LUMINANCE		,
		PIXEL_TYPE_LUMINANCE_ALPHA	,	//	LA
		PIXEL_TYPE_BGR				,	//	BGR		- 24 bits.
		PIXEL_TYPE_ABGR				,	//	ABGR	- 32 bits.
		PIXEL_TYPE_RGB				,
		PIXEL_TYPE_ARGB				,

		_PIXEL_TYPE_CNT				,
		_PIXEL_TYPE_VER	= 0			,
	};

	enum ENUM_RENDER_DEVICE_TYPE
	{
		RENDER_DEVICE_TYPE_NULL		,	//
		RENDER_DEVICE_TYPE_DEFAULT	,	//
		RENDER_DEVICE_TYPE_OPENGL	,	//
		RENDER_DEVICE_TYPE_D3D		,	//
	};

	enum	ENUM_USAGE_TYPE
	{
		USAGE_TYPE_OPTION_DRAW		= 0x01	,	//	用来绘制
		USAGE_TYPE_OPTION_READ		= 0x02	,	//	用来读
		USAGE_TYPE_OPTION_COPY		= 0x04	,	//	用来复制

		USAGE_TYPE_STRATEGY_STREAM	= 0x10	,	//	流数据
		USAGE_TYPE_STRATEGY_DYNAMIC	= 0x20	,	//	动态数据
		USAGE_TYPE_STRATEGY_STATIC	= 0x30	,	//	静态数据

		_USAGE_TYPE_BITS_SIZE		= 0x06	,
	};
}}


class	LOLIX_NO_VTABLE	lolix::pretty::canvas_package
	: public itf
{
public:
	typedef	void*	platform_win_handle;

	LOLIX_DEFINE_FACTORY((0x8fb2cd64, 0xeedd406b, 0xaa55c1b7, 0x9e5fd4cd), (canvas_package** out_ptr, platform_win_handle, ENUM_RENDER_DEVICE_TYPE));
	LOLIX_DECLARE_ITF(lolix::pretty::canvas_package, lolix::itf, (0x434ec87d, 0xdb8d4df0, 0xbdfc9a39, 0x2a0cde4f));

	class	buffer_depth;
	class	render_body;
	class	render_material;
	class	render_mesh;
	class	render_properties;
	class	render_texture;
	class	render_params;

	typedef	render_body			r_body;
	typedef	render_material		r_material;
	typedef	render_mesh			r_mesh;
	typedef	render_properties	r_prop;
	typedef	render_texture		r_tex;
	typedef	render_params		r_params;

	typedef	buffer_depth		b_dep;		//	深度缓冲区

	//LOLIX_INTERFACE_DEPRECATED(set_option		, LOLIX_RETNV, (size_type opt_type, const size_type* param), "use render_properties instander");
	//LOLIX_INTERFACE_DEPRECATED(get_option		, LOLIX_RETNV, (size_type opt_type, size_type* out_ptr)const, "use render_properties instander");
	typedef	union _tagDepthBufferParams
	{
		typedef	lx_u32	flag_type;
		LOLIX_INLINE_CALL	_tagDepthBufferParams(void){}
		LOLIX_INLINE_CALL	_tagDepthBufferParams(flag_type flg):_flag(flg){}
		LOLIX_INLINE_CALL	_tagDepthBufferParams(init_for_nothing_copy){}

		LOLIX_INLINE_CALL	void set_flag(flag_type flg)		{_flag = flg;}
		LOLIX_INLINE_CALL	void set_bits(flag_type bits_size)	{_bits_size = 4 - ((bits_size >> 3) & 0x3);}
		LOLIX_INLINE_CALL	void set_width(flag_type width)		{_width = width;}
		LOLIX_INLINE_CALL	void set_height(flag_type height)	{_height = height;}

		LOLIX_INLINE_CALL	flag_type get_flag(void)const		{return _flag;}
		LOLIX_INLINE_CALL	flag_type get_bits(void)const		{return (4 - _bits_size) << 3;}
		LOLIX_INLINE_CALL	flag_type get_width(void)const		{return _width;}
		LOLIX_INLINE_CALL	flag_type get_height(void)const		{return _height;}

#if			defined(LOLIX_DEF__CC_TYPE_MS)
		__declspec(property(get = get_flag	, put = set_flag))		flag_type	flag;
		__declspec(property(get = get_bits	, put = set_bits))		flag_type	bits;
		__declspec(property(get = get_width	, put = set_width))		flag_type	width;
		__declspec(property(get = get_height, put = set_height))	flag_type	height;
#endif	//	defined(LOLIX_DEF__CC_TYPE_MS)
	private:
__BEGIN_DISABLE_NO_NAME_STRUCT_WARNING();
		struct
		{
		flag_type	_bits_size	: 2;
		flag_type	_width		:14;
		flag_type	_height		:14;
		flag_type	_reserver	: 2;
		};
__END_DISABLE_NO_NAME_STRUCT_WARNING();

		flag_type	_flag;
	}b_deepth_params;
	STATIC_ASSERT(sizeof (b_deepth_params) == sizeof (b_deepth_params::flag_type));

	//	create depth buffer
	LOLIX_INTERFACE(c_bdep	, LOLIX_RETNV	, (buffer_depth**, _tagDepthBufferParams param));
	//	创建一个绘制上下文
	//	depth_buffer_bits : 缓冲区的位数， 16, 24, 32 等， 0 表示不创建默认深度缓冲区
	//LOLIX_INTERFACE(create_canvas	, LOLIX_RETNV	, (canvas** out_ptr, size_type depth_buffer_bits));

	//===========================================================================
	//	将 canvas 的内容提交到 palette 上面去
	//---------------------------------------------------------------------------
	//	tex			[i ]	:	需要提交的纹理
	//	tex_pos		[i ]	:	为使用渲染平面的  x, y, width, height, 0 表示全部
	//	tex_uv		[i ]	:	为使用 uv 的 x, y, width, height, 0 表示全部
	//===========================================================================
	LOLIX_INTERFACE(submit	, LOLIX_RETNV	, (render_texture* tex, const lx_u16* tex_pos/* = 0*/, const float* tex_uv /* = 0 */));
};


class	LOLIX_NO_VTABLE	lolix::pretty::canvas_package::buffer_depth
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::canvas_package::buffer_depth, lolix::itf, (0x00671d7a, 0x0d2a4052, 0x8232173a, 0x9774ce68));
	typedef	canvas_package::_tagDepthBufferParams	_tagDepthBufferParams;
	typedef	canvas_package::b_deepth_params			b_deepth_params;
	//	得到深度缓冲区的位数
	LOLIX_INTERFACE(get_params	, LOLIX_RETNV	, (_tagDepthBufferParams* out_ptr)const);
};


class	LOLIX_NO_VTABLE	lolix::pretty::canvas
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::canvas, lolix::itf, (0xb6b3cc3f, 0x2e304536, 0x968b4e9e, 0xf44dfb3a));

	enum	ENUM_CANVAS_ELEMENT
	{
		CANVAS_ELEMENT_COLOR	= 1,
		CANVAS_ELEMENT_DEPTH	= 2,
	};

	enum	ENUM_CANVAS_OPTION
	{
		CANVAS_OPTION_VIEWPORT		,	//	io. lx_u32 4 param (x, y, width, height)
		CANVAS_OPTION_CLEAR_COLOR	,	//	io. float 4. (r, g, b, a):[0.0, 1.0]
		CANVAS_OPTION_CLEAR_DEPTH	,	//	io. float 1.0 [0.0, 1.0]
	};

	//	ENUM_CANVAS_ELEMENT
	LOLIX_INTERFACE(clear			, LOLIX_RETNV,	(size_type canvas_elemnt));

	LOLIX_INTERFACE(set_modelview	, LOLIX_RETNV,	(const sola::dmat4* mat, bool right));
	LOLIX_INTERFACE(get_modelview	, LOLIX_RETNV,	(sola::dmat4* mat, bool* right)const);
	//	left, right, bottom, top, near, far
	LOLIX_INTERFACE(frustum			, LOLIX_RETNV,	(const double frustum[6]));
	LOLIX_INTERFACE(ortho			, LOLIX_RETNV,	(float left, float right, float bottom, float top));

	LOLIX_INTERFACE(set_option		, LOLIX_RETNV,	(size_type opt_type, const void* param));
	LOLIX_INTERFACE(get_option		, LOLIX_RETNV,	(size_type opt_type, void* out_ptr)const);

	LOLIX_INTERFACE(set_fragdata	, LOLIX_RETNV,	(canvas_package::render_texture* const* inptr, size_type incnt));
	LOLIX_INTERFACE(get_fragdata	, LOLIX_RETNV,	(canvas_package::render_texture** outptr, size_type from, size_type* iocnt));

	//--------------------------------------------------------------------------
	//	>> 2008-12-03 00:23:02 >>------------------->> 2008-12-03 00:23:02 >>
		//FUNC>>$	:设置渲染上下文的深度缓冲区
			//FUNC>>@0	:[in]	深度缓冲区， 内部会自动调用 inc_ref
			//FUNC>>@1	:[out]	原始的深度缓冲区， 如果该指针为0， 则不会传出原始缓冲区， 此时内部会自动把该对象 release
				//FUNC>>#	:成功则返回 LOLIX_RETNV_OK, 其他状况返回各式失败
	//--------------------------------------------------------------------------
	LOLIX_INTERFACE(set_bdep		, LOLIX_RETNV,	(canvas_package::buffer_depth* dep_buf, canvas_package::buffer_depth** out /* = 0 */));

	//--------------------------------------------------------------------------
	//	>> 2007-05-26 16:35:23 >>------------------->> 2007-05-26 16:35:23 >>
		//FUNC>>$	:渲染对象
			//FUNC>>@0	:[in] 等待渲染对象的数组
			//FUNC>>@1	:[in] 等待渲染对象的数组的数量,	ARRAY_SIZE 所指代的含义
				//FUNC>>#	:
	//--------------------------------------------------------------------------
	LOLIX_INTERFACE(render_bodies	, LOLIX_RETNV	, (canvas_package::render_material*, canvas_package::render_body** rbd, size_type rbd_size));
};


class	LOLIX_NO_VTABLE	lolix::pretty::canvas_package::render_body
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::canvas_package::render_body, lolix::itf, (0x6fc5449e, 0xd4b1485b, 0x86af225e, 0x20ae4ac0));

	LOLIX_INTERFACE(attach_mesh		,	LOLIX_RETNV,	(render_mesh*));
	LOLIX_INTERFACE(catch_mesh		,	LOLIX_RETNV,	(render_mesh**));

	LOLIX_INTERFACE(get_dancer		,	LOLIX_RETNV,	(const sola::dancer**)const);
	LOLIX_INTERFACE(catch_dancer	,	LOLIX_RETNV,	(sola::dancer**));
	//	如果出参不为空， 则需要手工 release 掉交换出来的 ptr
	LOLIX_INTERFACE(swap_dancer		,	LOLIX_RETNV,	(sola::dancer* in_ptr, sola::dancer** out_ptr));
};


////////////////////////////////////////////////////////////////////////////
//CLASS>>$	:参数， 包含 一套材质对应的常数参数， 可以通过 material 请求出默认的数据
////////////////////////////////////////////////////////////////////////////
class	LOLIX_NO_VTABLE	lolix::pretty::canvas_package::render_params
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::canvas_package::render_params, lolix::itf, (0xa9e803b8, 0xd0d542dd, 0xad4cf943, 0xf3f9d16c));

	LOLIX_INTERFACE(set_idx		, LOLIX_RETNV	, (ENUM_IDX_TYPE idx_type, const char* const name[], size_type name_len[], size_type idx[], size_type array_size));
	LOLIX_INTERFACE(set_unif_f	, LOLIX_RETNV	, (size_type idx, const float* in_f, size_type buf_cnt));
	LOLIX_INTERFACE(set_unif_i	, LOLIX_RETNV	, (size_type idx, const int* in_i, size_type buf_cnt));
	LOLIX_INTERFACE(set_tex		, LOLIX_RETNV	, (size_type idx, render_texture*));
};


////////////////////////////////////////////////////////////////////////////
//CLASS>>$	:材质， 包含 一套渲染环境
////////////////////////////////////////////////////////////////////////////
class	LOLIX_NO_VTABLE	lolix::pretty::canvas_package::render_material
	: public itf
{
	LOLIX_DECLARE_ITF(lolix::pretty::canvas_package::render_material, lolix::itf, (0x2b17e9df, 0x3760457b, 0xb4aa0a0f, 0x5003421f));
	typedef	canvas_package::render_properties		render_properties;
	typedef	canvas_package::render_texture			render_texture;
	LOLIX_INTERFACE(catch_params, LOLIX_RETNV	, (render_params** in_ptr));
	LOLIX_INTERFACE(catch_prop	, LOLIX_RETNV	, (render_properties** out_ptr));
	LOLIX_INTERFACE(get_params	, LOLIX_RETNV	, (const render_params** in_ptr)const);
	LOLIX_INTERFACE(get_prop	, LOLIX_RETNV	, (const render_properties** out_ptr)const);
};

////////////////////////////////////////////////////////////////////////////
//CLASS>>$	:mesh 包含一组格式良好的顶点
////////////////////////////////////////////////////////////////////////////
class	LOLIX_NO_VTABLE	lolix::pretty::canvas_package::render_mesh
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::canvas_package::render_mesh, lolix::itf, (0x09c77d53, 0x9a244e88, 0xb5384c72, 0x5528e2fc));
	enum { opt_read = 1, opt_write = 2 };
	enum ENUM_BUFFER_TYPE{BUFFER_TYPE_VERTEX, BUFFER_TYPE_INDEX, _BUFFER_TYPE_CNT, _BUFFER_TYPE_VER = 0};
	enum ENUM_MAPPING_TYPE {MAPPING_TYPE_NULL, MAPPING_TYPE_READ, MAPPING_TYPE_WRITE, MAPPING_TYPE_READ_WRITE};
	enum ENUM_VERTEX_TYPE
	{
		VERTEX_TYPE_UNKNOWS			,	//	未知
		VERTEX_TYPE_POINTS			,	//	点
		VERTEX_TYPE_LINES			,	//	线
		VERTEX_TYPE_STRIP_LINES		,	//	首尾连接的线
		VERTEX_TYPE_LOOP_LINES		,	//	乱七八糟的线
		VERTEX_TYPE_TRIANGLES		,	//	三角形
		VERTEX_TYPE_STRIP_TRIANGLES	,	//	三角条
		VERTEX_TYPE_LOOP_TRIANGLES	,	//	三角形扇（果然还是很乱）

		_VERTEX_TYPE_CNT			,	//	
		_VERTEX_TYPE_VER			= 0	//	
	};

	struct	mesh_info
	{
		enum {_VER = 2};

		enum { MAX_ATTR_SIZE_POW = 5 };
		enum { VTX_TYPE_SIZE = toy::size_info<_VERTEX_TYPE_CNT - 1>::size_bits };
		enum { IDX_TYPE_BITS_SIZE = lolix::toy::size_info<lolix::_VALUE_TYPE_CNT-1>::size_bits };

		lx_u32	vtx_type	: _VERTEX_TYPE_CNT;		//	这里是什么东西		ENUM_VERTEX_TYPE
		lx_u32	attr_size	: MAX_ATTR_SIZE_POW;	//	有多少个分量呢(比如有顶点数据, 颜色数据, 法线数据, 就是3) 0 == max
		lx_u32	idx_type	: IDX_TYPE_BITS_SIZE;	//	索引的类型是什么:	lolix::ENUM_VALUE_TYPE
	};

	struct	vtx_info
	{
		typedef	lx_u64			value_type;
		enum {_VER = 1};
		value_type	vt_offset	:32;		//	vertex 属性的整体偏移
		value_type	vt_stride	:16;		//	每个元素对齐大小是多少
		value_type	vt_size		: 3;		//	有多少个分量呢 1, 2, 3, or 4
		value_type	vt_type		: toy::size_info<_VALUE_TYPE_CNT>::size_bits;		//	是什么类型的呢
		value_type	vt_idx		: 7;		//	属性的索引值，所绑定的 ID
	};

	struct	buf_info
	{
		typedef lx_u64			value_type;
		enum { _VER = 0};
		value_type bf_size	: 32;
		value_type bf_usage	: _USAGE_TYPE_BITS_SIZE;
	};

	//LOLIX_INTERFACE(lock_mesh	, LOLIX_RETNV, (vertex_buffer*, size_type lock_type));
	//LOLIX_INTERFACE(unlock		, LOLIX_RETNV, (const vertex_buffer*));
	LOLIX_INTERFACE(elm_cnt		, LOLIX_RETNV, (size_type* out_size)const);
	LOLIX_INTERFACE(get_binf	, LOLIX_RETNV, (buf_info* inf, ENUM_BUFFER_TYPE buf_type)const);

	LOLIX_INTERFACE(set_minf	, LOLIX_RETNV, (const mesh_info* elm_cnt));
	LOLIX_INTERFACE(get_minf	, LOLIX_RETNV, (mesh_info* elm_cnt)const);

	LOLIX_INTERFACE(set_vinf	, LOLIX_RETNV, (const vtx_info* inf, size_type pos));
	LOLIX_INTERFACE(get_vinf	, LOLIX_RETNV, (vtx_info* inf, size_type pos)const);

	//===========================================================================
	//	设置缓冲区的数据
	//---------------------------------------------------------------------------
	//	dat			[i ] :	数据指针地址, 为空表示不初始化数据
	//	buf_type	[i ] :	缓冲区类型
	//	space_size	[i ] :	申请的数据大小
	//	usage_type	[i ] :	使用的描述数据
	//---------------------------------------------------------------------------
	//	dat 不为0的场合, 其 dat 的实际长度必须大于或者等于 space_size
	//===========================================================================
	LOLIX_INTERFACE(buf_dat		, LOLIX_RETNV, (const void* dat, ENUM_BUFFER_TYPE buf_type, size_type space_size, size_type usage_type));

	//===========================================================================
	//	映射数据到内存中
	//---------------------------------------------------------------------------
	//	buf_ptr		[ o] :	内部数据的返回地址
	//	buf_type	[i ] :	映射哪一个缓冲区
	//	map_type	[i ] :	使用何种权限操作
	//---------------------------------------------------------------------------
	//===========================================================================
	LOLIX_INTERFACE(mapping		, LOLIX_RETNV, (void** buf_ptr, ENUM_BUFFER_TYPE buf_type, ENUM_MAPPING_TYPE map_type));

	//===========================================================================
	//	完成映射操作
	//---------------------------------------------------------------------------
	//	buf_ptr		[i ] :	需要解除映射的地址
	//	buf_type	[i ] :	需要解除映射的缓冲区类型
	//---------------------------------------------------------------------------
	//===========================================================================
	LOLIX_INTERFACE(unmapping	, LOLIX_RETNV, (const void* buf_ptr, ENUM_BUFFER_TYPE buf_type));


	//===========================================================================
	//	激活缓冲区有效数据长度 : 元素数量
	//---------------------------------------------------------------------------
	//	active_size	[io] :	i)需要激活的长度 o)原始激活的长度
	//---------------------------------------------------------------------------
	//===========================================================================
	LOLIX_INTERFACE(make_active	, LOLIX_RETNV, (size_type* active_size));
#if			0
	//===========================================================================
	//	设置属性行的值
	//---------------------------------------------------------------------------
	//	vtx_type		[i ]	属性类型
	//	val_type		[i ]	属性的值类型
	//	offset			[i ]	属性的起始从缓冲区的多少长度开始 (byte)
	//	stride			[i ]	每组属性之间间隔多少
	//	elm_size		[i ]	每组属性有多少个单元 [1, 4]
	//	in_data			[i ]	属性数据
	//	data_size		[i ]	属性数据的总长度(byte)
	//---------------------------------------------------------------------------
	//	返回值说明
	//---------------------------------------------------------------------------
	//	特别注释:	in_data 的值可以取真实物理地址， 也可以取 ENUM_VTX_TYPE 中的数据
	//				当 data 的数据为 ENUM_VTX_TYPE 具体类别时， 表示说这两个类型拥有
	//				相同的属性数据缓冲区， 此时， data_size 必须为 0
	//===========================================================================
	LOLIX_INTERFACE(set_att	, lolix::LOLIX_RETNV	, (ENUM_VTX_TYPE  in_vtx_type, ENUM_VALUE_TYPE in_val_type
													, size_type in_offset, size_type in_stride, size_type in_elm_size
													, const void* in_data, size_type in_data_size));

	//===========================================================================
	//	设置索引缓冲区内容
	//---------------------------------------------------------------------------
	//	vtx_type		[i ]	mesh 类型
	//	val_type		[i ]	索引数据的类型
	//	idx_byte_size	[i ]	索引的长度 : 字节数
	//	in_ptr			[i ]	索引缓冲区
	//===========================================================================
	LOLIX_INTERFACE(set_idx	, lolix::LOLIX_RETNV	, (VERTEX_TYPE in_vtx_type, ENUM_VALUE_TYPE in_val_type
													, const void* in_ptr, size_type in_idx_byte_size));


	//===========================================================================
	//	申请一块内部内存
	//---------------------------------------------------------------------------
	//	ptr				[ o]	返回的内部内存首地址（没有对齐）
	//	len				[i ]	申请的地址长度
	//---------------------------------------------------------------------------
	//	#:	此时可以把返回的值作为 set_idx, set_att 里面的那个指针传递进去；
	//		同时， in_data_size 依旧必须为 0
	//===========================================================================
	LOLIX_INTERFACE(mapping	, lolix::LOLIX_RETNV	, (void** in_ptr, size_type in_len));

	//===========================================================================
	//	取消一个申请的内存
	//---------------------------------------------------------------------------
	//	ptr				[i ]	申请偿还的内存
	//---------------------------------------------------------------------------
	//	#:	使用 set 函数设置到内部的内存不需要调用这个值来返回了
	//===========================================================================
	LOLIX_INTERFACE(unmapping,	void				, (const void* in_ptr));

#endif	//	0

};


////////////////////////////////////////////////////////////////////////////
//CLASS>>$	:状态， 包含 一套渲染方法
////////////////////////////////////////////////////////////////////////////
class	LOLIX_NO_VTABLE	lolix::pretty::canvas_package::render_properties
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::canvas_package::render_properties, lolix::itf, (0x1a79b7b7, 0xe4f547e6, 0x98aee46b, 0x94153ad5));
	enum	ENUM_BLEND_FUNC
	{											//	(R, G, B, A)
		BLEND_FUNC_ZERO						,	//	(0, 0, 0, 0)
		BLEND_FUNC_ONE						,	//	(1, 1, 1, 1)
		BLEND_FUNC_SRC_COLOR				,	//	S
		BLEND_FUNC_ONE_MINUS_SRC_COLOR		,	//	1 - S
		BLEND_FUNC_DST_COLOR				,	//	D
		BLEND_FUNC_ONE_MINUS_DST_COLOR		,	//	1 - D
		BLEND_FUNC_SRC_ALPHA				,	//	(As, As, As, As)
		BLEND_FUNC_ONE_MINUS_SRC_ALPHA		,	//	1 - (As, As, As, As)
		BLEND_FUNC_DST_ALPHA				,	//	(Ad, Ad, Ad, Ad)
		BLEND_FUNC_ONE_MINUS_DST_ALPHA		,	//	1 - (Ad, Ad, Ad, Ad)
		BLEND_FUNC_CONSTANT_COLOR			,	//	(C, C, C, C)
		BLEND_FUNC_ONE_MINUS_CONSTANT_COLOR	,	//	1 - (C, C, C, C)
		BLEND_SRC_ALPHA_SATURATE			,	//	(f, f, f, 1) f = min(As, 1-Ad)

		_BLEND_CNT							,
		_BLEND_VER = 0						,
	};

	enum	ENUM_BLEND_EQUATION
	{
		BLEND_EQUATION_NONE				,	//	no blend
		BLEND_EQUATION_ADD				,	//	Cs * S + Cd * D
		BLEND_EQUATION_SUBTRACT			,	//	Cs * S - Cd * D
		BLEND_EQUATION_REVERSE_SUBTRACT	,	//	Cd * D - Cs * S
		BLEND_EQUATION_MIN				,	//	min(Cs, Cd)
		BLEND_EQUATION_MAX				,	//	max(Cs, Cd)

		_BLEND_EQUATION_CNT				,
		_BLEND_EQUATION_VER = 0			,
	};

	enum	ENUM_COMPARE_FUNC
	{
		COMPARE_FUNC_ALWAYS			,
		COMPARE_FUNC_NEVER			,
		COMPARE_FUNC_LESS			,
		COMPARE_FUNC_LESS_EQUAL		,
		COMPARE_FUNC_EQUAL			,
		COMPARE_FUNC_NOT_EQUAL		,
		COMPARE_FUNC_EQUAL_LARGE	,
		COMPARE_FUNC_LARGE			,

		_COMPARE_FUNC_CNT			,
		_COMPARE_FUNC_VER = 1		,
	};

	enum	ENUM_POLYGONMODE_TYPE
	{
		POLYGONMODE_TYPE_FILL	,
		POLYGONMODE_TYPE_LINE	,
		POLYGONMODE_TYPE_POINT	,
		POLYGONMODE_TYPE_NULL	,	//	不渲染
		_POLYGONMODE_TYPE_CNT	,
		_POLYGONMODE_TYPE_VER = 1
	};


#pragma	pack(push, 4)
__BEGIN_DISABLE_NO_NAME_STRUCT_WARNING();
	typedef	struct	_tagRenderPropBase
	{
		union
		{
			enum	{ _VER = 0 };
		typedef	lx_u32	flag_type;
			struct
			{
		flag_type					:16;
		flag_type	depth_test		: 3;	//	ENUM_COMPARE_FUNC default = COMPARE_FUNC_ALWAYS
		flag_type	alpha_blend		: 1;	//	0: no, 1: blend
			};

			struct
			{
		flag_type					:20;
		flag_type	blend_src		: 4;
		flag_type	blend_dst		: 4;
		flag_type	blend_equ		: 3;	//	ENUM_COMPARE_FUNC
			};

			struct
			{
		flag_type	frnt_polyg_mode	: 2;	//	ENUM_POLYGONMODE_TYPE
		flag_type	back_polyg_mode	: 2;
		flag_type	cull_mode		: 2;	//	1 : cull back, 2 : cull front, 3 : cull all, [0] : cull none
			};

			struct
			{
		flag_type	all_flag		:31;
		flag_type	_reverse		: 1;
			};

		flag_type	prop_flag;
		};
	}prop_info;
__END_DISABLE_NO_NAME_STRUCT_WARNING();

	typedef struct _tagRenderPropWithAlphaBlendCompareConst
		: public _tagRenderPropBase
	{
		//	如果 blend 开启， 并且源指定了 CONST,  则这个地方为 argb 顺序的颜色值
		//	因此， 根据设定， 这个地方最多只有 4 个数据而已
		float	blend_const[4];	//	附加数据
	}prop_info_with_const_color;

#pragma	pack(pop)

	//LOLIX_INTERFACE(attach_log	, LOLIX_RETNV		, (loli::file_block* log));
	LOLIX_INTERFACE(complier	, LOLIX_RETNV		, (const char* const, size_type sslen, ENUM_SHADER_TYPE ss_type));
	LOLIX_INTERFACE(link		, LOLIX_RETNV		, (void));

	LOLIX_INTERFACE(set_prop	, LOLIX_RETNV		, (const prop_info*));
	LOLIX_INTERFACE(get_prop	, const prop_info*	, (void)const);
};


class	LOLIX_NO_VTABLE	lolix::pretty::canvas_package::render_texture
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::canvas_package::render_texture, lolix::itf, (0x068dc718, 0x0111491f, 0xaa5551a8, 0x33763d3b));
	enum TEX_TGT
	{
		t_xd	,	//	未知纹理属性
		t_1d	,
		t_2d	,
		t_3d	,
		t_cube	,
		t_2dr	,	//	2D rect texture

		t_cnt	,	//	计数
		t_ver = 0,	//	枚举版本
	};

	enum	ENUM_WRAP_TYPE
	{
		WRAP_REPEAT				,
		WRAP_CLAMP				,
		WRAP_MIRRORED_REPEAT	,
		WRAP_CLAMP_TO_BORDER	,
		WRAP_CLAMP_TO_EDGE		,
		WRAP_TYPE_CNT			,
		WRAP_TYPE_VER		= 1,
	};

	enum	ENUM_FILTER_TYPE
	{
		FILTER_NEAREST					,
		FILTER_LINEAR					,
		FILTER_NEAREST_MIPMAP_NEAREST	,
		FILTER_NEAREST_MIPMAP_LINEAR	,
		FILTER_MIPMAP_LINEAR			,

		FILTER_TYPE_CNT					,
		FILTER_TYPE_VER	= 0				,
	};

#pragma	pack(push, 2)
	typedef	struct	_tagTexFmt
	{
		lx_u32	tx_fmt		: 4;	//	PIXEL_TYPE
		lx_u32	tx_type		: 4;	//	ELEMENT_TYPE
		lx_u32	border		: 3;	//	边界多少
		lx_u32	compress	: 2;	//	是否压缩纹理(0, 不压缩, 1 最快 2 最好 3 无所谓
	}tex_fmt;
#pragma	pack(4)

	typedef	struct	_tagTextureCfg
	{
__BEGIN_DISABLE_NO_NAME_STRUCT_WARNING();
		union
		{
			struct{
		lx_u32	lod_img_bits:16;	//	0 ~ 16
		lx_u32	lod_img_size: 5;
		lx_u32	is_resident	: 1;	//	是否是常驻纹理
		lx_u32	auto_mipmap	: 1;	//	开启自动 mipmap
		lx_u32				: 2;
		lx_u32	have_flag	: 7;
			};
			struct{
		lx_u32				:25;
		lx_u32	have_anis	: 1;
		lx_u32	have_automip: 1;
		lx_u32	have_bc		: 1;	//	border color
		lx_u32	have_filter	: 1;
		lx_u32	have_load	: 1;
		lx_u32	have_mip	: 1;
		lx_u32	have_wrap	: 1;
			};
		};
		//	32 bits
		lx_u32	w			:16;	//	多宽
		lx_u32	h			:16;	//	多高
		//	64 bits

		lx_u32	d			:16;	//	多厚
		lx_u32	mip_min		: 4;	//	用于 min 的最小 lod 数
		lx_u32	mip_max		: 4;	//	用于 min 的最大 lod 数
		lx_u32	load_min	: 4;	//	载入的最小 lod
		lx_u32	load_max	: 4;	//	载入的最大 lod
		//	96 bits

		lx_u32	tx_anis		: 5;	//	anisotropy_level
		lx_u32	tx_tgt		: 3;	//	是什么类型的 Texture? : TEX_TGT
		lx_u32	filter_min	: 3;
		lx_u32	filter_mag	: 3;

		lx_u32	wrap_s		: 3;	//	WRAP_TYPE
		lx_u32	wrap_t		: 3;	//	WRAP_TYPE
		lx_u32	wrap_r		: 3;	//	WRAP_TYPE
		lx_u32				: 9;	//	

		//	128 bits
		union{//	border color
			struct{
		lx_u32	bc_red		: 8;
		lx_u32	bc_green	: 8;
		lx_u32	bc_blue		: 8;
		lx_u32	bc_alpha	: 8;
			};
		lx_u32	bc_rgba		:32;
		};

		//	160 bits
		LOLIX_INLINE_CALL	const tex_fmt* sub_fmt(void)const{return reinterpret_cast<const _tagTexFmt*>(this+1);}
		LOLIX_INLINE_CALL	tex_fmt* sub_fmt(void){return reinterpret_cast<_tagTexFmt*>(this+1);}
__END_DISABLE_NO_NAME_STRUCT_WARNING();
	}tex_cfg;
	STATIC_ASSERT(sizeof tex_cfg == 20);


	typedef	struct	_tagTexImage
	{
		lx_u32	is_sub	: 1;	//	是不是仅填充数据
		lx_u32	lod_lev	: 4;	//	当前是多少层的 LOD
		lx_u32			:27;	//	填充空间
	}tex_img;

	typedef	struct	_tagTexSubImage
		: public _tagTexImage
	{
		lx_u32	x	:16;	//
		lx_u32	y	:16;	//

		lx_u32	z	:16;	//
		lx_u32	w	:16;	//	多宽

		lx_u32	h	:16;	//	多高
		lx_u32	d	:16;	//	多厚
	}tex_sub_img;

#pragma	pack(pop)

	//	必须指定 lod_img_bits, 来确定需要设定的子层级属性 : 在这个场合下, 必须确保有足够的缓冲区来完成此工作
	//	缓冲区长度通过 lod_img_size 来指定, 任何一个触发条件, 都将会返回操作
	LOLIX_INTERFACE(get_fmt		,	LOLIX_RETNV,	(tex_cfg* out_ptr)const);
	LOLIX_INTERFACE(get_img		,	LOLIX_RETNV,	(tex_img const* out_ptr, void* ptr)const);
	LOLIX_INTERFACE(set_fmt		,	LOLIX_RETNV,	(tex_cfg const* in_ptr));
	LOLIX_INTERFACE(set_img		,	LOLIX_RETNV,	(tex_img const* in_img, void* ptr));
};




//--------------------------------------------------------------------------
//==============================================================================
SYS_REGIST_TYPE(lolix::pretty::canvas);
SYS_REGIST_TYPE(lolix::pretty::canvas_package);
SYS_REGIST_TYPE(lolix::pretty::canvas_package::_tagDepthBufferParams);
SYS_REGIST_TYPE(lolix::pretty::canvas_package::buffer_depth);
SYS_REGIST_TYPE(lolix::pretty::canvas_package::factory_type);
SYS_REGIST_TYPE(lolix::pretty::canvas_package::render_body);
SYS_REGIST_TYPE(lolix::pretty::canvas_package::render_material);
SYS_REGIST_TYPE(lolix::pretty::canvas_package::render_mesh);
SYS_REGIST_TYPE(lolix::pretty::canvas_package::render_params);
SYS_REGIST_TYPE(lolix::pretty::canvas_package::render_properties);
SYS_REGIST_TYPE(lolix::pretty::canvas_package::render_texture);

#endif	//	!defined(__LOLIX__PRETTY__CANVAS__K_IN_G__)
